#include "StdAfx.h"
#include "CarnivalBuilder.h"
#include "SgPolygon.h"
#include "ObservationTowerFactory.h"
#include "SgOctagonalCylinder.h"
#include "YoYoFactory.h"
#include "FerrisWheelFactory.h"
#include "ScramblerFactory.h"
#include "sgtranslate.h"
#include "sgseparator.h"
#include "sgrotate.h"
#include "SgTexture.h"
#include "SgSeparator.h"
#include "SgTranslate.h"
#include "SgMesh.h"
#include <gl/gl.h>
#include <string>
using namespace std;

#define GR_PI 3.14159265358979323846

CarnivalBuilder::CarnivalBuilder(void)
{
	//LoadTexture("marble", "marble02.bmp");

	//glColor3d(1.0, 0.0, 0.0);

	CSgPtr<CSgPolygon> p = new CSgPolygon();
	m_root = new CSgComposite();
	//m_root->IncRef();

	//if (!m_ground.LoadFile(L"grass01.bmp"))
	//	exit(1);

	m_ground.LoadFile(L"grass01.bmp");
	m_animate = false;
	m_sky1.LoadFile(L"NightSky01.bmp");
	m_sky2.LoadFile(L"NightSky02.bmp");
	m_sidewalk = new CTexture();
	m_sidewalk->LoadFile(L"sidewalk.bmp");
	m_lastTime = 0;

	//Carnival Ground/SkyBox
	CarnivalGrounds();
	Sidewalks();

	ObservationTower();
	
	Gravitron();
	Scrambler();
	FerrisWheel();


	Fences(); // moved down because of material (color) bleeding
	YoYo();
	//Fence
	
}

CarnivalBuilder::~CarnivalBuilder(void)
{

}

void CarnivalBuilder::StartAnimation(void)
{
	m_animate = true;
	m_lastTime = GetTickCount(); // avoid jerky animation
}

void CarnivalBuilder::StopAnimation(void)
{
	m_animate = false;
}

CTexture* CarnivalBuilder::GetTexture(const string & textureName)
{
	map<string, CTexture*>::iterator iter = m_textureBinder.find(textureName);
	if (iter != m_textureBinder.end())
		return iter->second;
	else
		return 0;
}

void CarnivalBuilder::LoadTexture(const string & textureName, const string & fileName)
{
	if (m_textureBinder.end() ==
		m_textureBinder.find(textureName))
	{
		// texture not found: let's load it
		
		m_textureBinder[textureName] = new CTexture();
		m_textureBinder[textureName]->LoadFile(fileName.c_str());
	}
}

void CarnivalBuilder::Render(DWORD dwTime)
{
	//if (m_root != NULL)
	//{

	if (m_animate)
	{
		const DWORD timeDiff = dwTime - m_lastTime;
		m_lastTime = dwTime; // should this be here or after m_root->Render()? adjust as needed... when it's here we account for Render() time

		// Ferris Wheel Animation
		m_fw.AdvanceTime(timeDiff, dwTime);

		// YoYo Animation
		m_yoyof.AdvanceTime(timeDiff, dwTime);

		//Scrambler Animation
		m_scrambler.AdvanceTime(timeDiff, dwTime);
		
		//Gravitron Animation
		m_Gravitron.AdvanceTime(timeDiff, dwTime);

		//Observation Tower Animation
		m_obs.AdvanceTime(timeDiff, dwTime);
	}

	m_root->Render();
	//}

	
}

void CarnivalBuilder::CarnivalGrounds()
{
	//Ground
	GLdouble g1[] = {0.,0.,0.};
	GLdouble g2[] = {0.,0.,100};
	GLdouble g3[] = {100,0.,100};
	GLdouble g4[] = {100,0.,0.};

	CSgPtr<CSgTexture> tex = new CSgTexture(&m_ground);
	
	CSgPtr<CSgPolygon> gr = new CSgPolygon();
	gr->AddNormal(CGrVector(0, 1, 0));
	gr->AddTexCoord(CGrVector(0, 0));
	gr->AddVertex(CGrVector(g1));
	gr->AddTexCoord(CGrVector(0, 100));
	gr->AddVertex(CGrVector(g2));
	gr->AddTexCoord(CGrVector(100, 0));
	gr->AddVertex(CGrVector(g3));
	gr->AddTexCoord(CGrVector(100, 100));
	gr->AddVertex(CGrVector(g4));

	tex->SetChild(gr);
	m_root->AddChild(tex);

	//North Face
	CSgPtr<CSgTexture> texN = new CSgTexture(&m_sky1);
	GLdouble n1[] = {0.,0.,0.};

	GLdouble n4[] = {0.,0.,100};
	GLdouble n3[] = {0,100.,100};
	GLdouble n2[] = {0.,100.,0.};


	CSgPtr<CSgPolygon> nf = new CSgPolygon();
	nf->AddNormal(CGrVector(1, 0, 0));
	nf->AddTexCoord(CGrVector(100, 100));
	nf->AddVertex(CGrVector(n1));
	nf->AddTexCoord(CGrVector(0, 0));
	nf->AddVertex(CGrVector(n2));
	nf->AddTexCoord(CGrVector(0, 100));
	nf->AddVertex(CGrVector(n3));
	nf->AddTexCoord(CGrVector(100, 0));
	nf->AddVertex(CGrVector(n4));
	texN->SetChild(nf);
	m_root->AddChild(texN);

	//South Face
	CSgPtr<CSgTexture> texS = new CSgTexture(&m_sky1);
	GLdouble s1[] = {100.,0.,0.};
	GLdouble s2[] = {100.,0.,100};
	GLdouble s3[] = {100,100.,100};
	GLdouble s4[] = {100.,100.,0.};


	CSgPtr<CSgPolygon> sf = new CSgPolygon();
	sf->AddNormal(CGrVector(1, 0, 0));
	sf->AddTexCoord(CGrVector(100, 0));
	sf->AddVertex(CGrVector(s1));
	sf->AddTexCoord(CGrVector(100, 100));
	sf->AddVertex(CGrVector(s2));
	sf->AddTexCoord(CGrVector(0, 0));
	sf->AddVertex(CGrVector(s3));
	sf->AddTexCoord(CGrVector(0, 100));
	sf->AddVertex(CGrVector(s4));
	texS->SetChild(sf);
	m_root->AddChild(texS);

	//East Face
	CSgPtr<CSgTexture> texE = new CSgTexture(&m_sky1);
	GLdouble e1[] = {0.,0.,100.};
	GLdouble e2[] = {0.,100.,100};
	GLdouble e3[] = {100.,100.,100};
	GLdouble e4[] = {100.,0.,100.};


	CSgPtr<CSgPolygon> ef = new CSgPolygon();
	ef->AddNormal(CGrVector(0, 0, -1));
	ef->AddTexCoord(CGrVector(0, 100));
	ef->AddVertex(CGrVector(e1));
	ef->AddTexCoord(CGrVector(100, 0));
	ef->AddVertex(CGrVector(e2));
	ef->AddTexCoord(CGrVector(100, 100));
	ef->AddVertex(CGrVector(e3));
	ef->AddTexCoord(CGrVector(0, 0));
	ef->AddVertex(CGrVector(e4));
	texE->SetChild(ef);
	m_root->AddChild(texE);

	//West Face
	CSgPtr<CSgTexture> texW = new CSgTexture(&m_sky1);
	GLdouble w1[] = {0.,0.,0.};
	GLdouble w2[] = {100.,0.,0};
	GLdouble w3[] = {100.,100.,0};
	GLdouble w4[] = {0.,100.,0.};


	CSgPtr<CSgPolygon> wf = new CSgPolygon();
	wf->AddNormal(CGrVector(0, 0, -1));
	wf->AddTexCoord(CGrVector(0, 0));
	wf->AddVertex(CGrVector(w1));
	wf->AddTexCoord(CGrVector(0, 100));
	wf->AddVertex(CGrVector(w2));
	wf->AddTexCoord(CGrVector(100, 0));
	wf->AddVertex(CGrVector(w3));
	wf->AddTexCoord(CGrVector(100, 100));
	wf->AddVertex(CGrVector(w4));
	texW->SetChild(wf);
	m_root->AddChild(texW);

	//Sky
	CSgPtr<CSgTexture> texSk = new CSgTexture(&m_sky2);

	GLdouble sky1[] = {0.,100.,0.};
	GLdouble sky2[] = {100.,100.,0};
	GLdouble sky3[] = {100.,100.,100.};
	GLdouble sky4[] = {0,100.,100.};

	CSgPtr<CSgMesh> sky = new CSgMesh();

	// paraboloid z=x^2/a^2 + y^2/b^2
	/*for (unsigned x = 0; x < 20; x++)
	{
		for (unsigned y = 0; y < 20; y++)
		{
			sky->AddNormal(CGrVector(0, 1, 0));
			const double z = x * x + y * y;
			sky->AddVertex(CGrVector(0, 5*y, 0));
			sky->AddVertex(CGrVector(5*x, 5*y, 0));
			sky->AddVertex(CGrVector(5*x, 5*y, 5*z));
			sky->AddVertex(CGrVector(0, 5*y, 5*z));
		}
	}*/

	/*const float c_x = 0;
	const float c_y = 0;
	const float r_x = 5.;
	const float r_y = 5.;
	const float r_z = 5.;
	const unsigned NUM_SIDES = 20;*/

	/*for (unsigned i = 0; i < NUM_SIDES; i++)
	{
		for (unsigned j = 0; j < NUM_SIDES; j++)
		{
			sky->AddNormal(CGrVector(0, 1, 0));

			const float z = ((i * i) + (j * j)) / 100.;*/

			/*sky->AddVertex(CGrVector(c_x + r_x*cos(2*GR_PI/(double)NUM_SIDES * i), c_y + r_y*sin(2*GR_PI/(double)NUM_SIDES * i), 0));
			sky->AddVertex(CGrVector(c_x + r_x*cos(2*GR_PI/(double)NUM_SIDES * (i+1)), c_y + r_y*sin(2*GR_PI/(double)NUM_SIDES * (i+1)), 0));
			sky->AddVertex(CGrVector(c_x + r_x*cos(2*GR_PI/(double)NUM_SIDES * (i+1)), c_y + r_y*sin(2*GR_PI/(double)NUM_SIDES * (i+1)), z));
			sky->AddVertex(CGrVector(c_x + r_x*cos(2*GR_PI/(double)NUM_SIDES * i), c_y + r_y*sin(2*GR_PI/(double)NUM_SIDES * i), z));*/
/*
			sky->AddVertex(CGrVector(i, j, 0));
			sky->AddVertex(CGrVector(i+1, j+1, 0));
			sky->AddVertex(CGrVector(i+1, j+1, z));
			sky->AddVertex(CGrVector(i, j, z));
		}
	}*/

	sky->AddNormal(CGrVector(0, 1, 0));
	sky->AddTexCoord(CGrVector(100, 100));
	sky->AddVertex(CGrVector(sky1));
	sky->AddTexCoord(CGrVector(0, 0));
	sky->AddVertex(CGrVector(sky2));
	sky->AddTexCoord(CGrVector(0, 100));
	sky->AddVertex(CGrVector(sky3));
	sky->AddTexCoord(CGrVector(100, 0));
	sky->AddVertex(CGrVector(sky4));

	/*const unsigned NUM_SIDES_X = 20;
	const unsigned NUM_SIDES_Y = 60;

	unsigned quad = 0; // our current quad

	for (unsigned i = 0; i < NUM_SIDES_X; i++)
	{
		for (unsigned j = 0; j < NUM_SIDES_Y; j++)
		{
			sky->AddNormal(CGrVector(0, 1, 0));

			const float z = ((i * i) + (j * j)) / 100.0f;

			// one quad on the paraboloid
			sky->AddVertex(CGrVector(c_x + i, c_y + j, 0));
			sky->AddVertex(CGrVector(c_x + i+1, c_y + j+1, 0));
			sky->AddVertex(CGrVector(c_x + i+1, c_y + j+1, z));
			sky->AddVertex(CGrVector(c_x + i, c_y + j, z));
			sky->AddFlatTexturedQuad(quad,quad+1,quad+2,quad+3,quad,CGrVector(0,0), CGrVector(0,1), CGrVector(1,0), CGrVector(1,1));
			quad += 4;
		}
	}*/

	//for (unsigned i = 0; i < NUM_SIDES_X * NUM_SIDES_Y * 4; i += 4)
	//	sky->AddFlatTexturedQuad(i, i+1, i+2, i+3, i, CGrVector(0,0), CGrVector(0,1), CGrVector(1,0), CGrVector(1,1));

	texSk->SetChild(sky);
	m_root->AddChild(texSk);


	
}

void CarnivalBuilder::Fences()
{
	/*****************************
	// Fences around YoYo
	*****************************/
	CSgPtr<CSgComposite> m_yoyofences = new CSgComposite();

		
	for (int l=0;l<40;l++)
	{

		CSgPtr<CSgComposite> m_fence = new CSgComposite();
		m_fence->AddChild(Fence());

		if (l<10) // left side
		{
			CSgPtr<CSgRotate> r1 = new CSgRotate(90.0f,0,1,0);
			r1->SetChild(m_fence);
			CSgPtr<CSgTranslate> tr1 = new CSgTranslate(20.0f, 0.0f, (2.0f * l) + 2.0f);
			tr1->SetChild(r1);
			CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
			sep1->SetChild(tr1);

			m_yoyofences->AddChild(sep1);
		}
		else if (l<20) // front
		{
			if(l == 15)
				continue;
			CSgPtr<CSgTranslate> tr2 = new CSgTranslate((2.0f * (l-10)) + 21.0f, 0.0f, 21.0f);
			tr2->SetChild(m_fence);
			CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
			sep2->SetChild(tr2);

			m_yoyofences->AddChild(sep2);
		}
		else if (l<30) // right
		{
			CSgPtr<CSgRotate> r2 = new CSgRotate(90.0f,0,1,0);
			r2->SetChild(m_fence);
			CSgPtr<CSgTranslate> tr3 = new CSgTranslate(40.0f, 0.0f, (2.0f * (l-20)) + 2.0f);
			tr3->SetChild(r2);
			CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
			sep3->SetChild(tr3);

			m_yoyofences->AddChild(sep3);
		}
		else
		{
			CSgPtr<CSgTranslate> tr4 = new CSgTranslate((2.0f * (l-30)) + 21.0f, 0.0f, 1.0f);
			tr4->SetChild(m_fence);
			CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
			sep4->SetChild(tr4);

			m_yoyofences->AddChild(sep4);
		}
		CSgPtr<CSgMaterial> fenceMatYEL = new CSgMaterial(50.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f);
		fenceMatYEL->SetChild(m_yoyofences);

		CSgPtr<CSgSeparator> sepYOYO = new CSgSeparator();
		sepYOYO->SetChild(fenceMatYEL);
		m_root->AddChild(sepYOYO);


	}


	{
		CSgPtr<CSgComposite> m_fwfences = new CSgComposite();

			
		for (int l=0;l<40;l++)
		{

			CSgPtr<CSgComposite> m_fence = new CSgComposite();
			m_fence->AddChild(Fence());

			if (l<10) // left side
			{
				CSgPtr<CSgRotate> r1 = new CSgRotate(90.0f,0,1,0);
				r1->SetChild(m_fence);
				CSgPtr<CSgTranslate> tr1 = new CSgTranslate(45.0f, 0.0f, (2.0f * l) + 2.0f);
				tr1->SetChild(r1);
				CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
				sep1->SetChild(tr1);

				m_fwfences->AddChild(sep1);
			}
			else if (l<20) // front
			{
				if(l == 15)
					continue;
				CSgPtr<CSgTranslate> tr2 = new CSgTranslate((2.0f * (l-10)) + 46.0f, 0.0f, 21.0f);
				tr2->SetChild(m_fence);
				CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
				sep2->SetChild(tr2);

				m_fwfences->AddChild(sep2);
			}
			else if (l<30) // right
			{
				CSgPtr<CSgRotate> r2 = new CSgRotate(90.0f,0,1,0);
				r2->SetChild(m_fence);
				CSgPtr<CSgTranslate> tr3 = new CSgTranslate(65.0f, 0.0f, (2.0f * (l-20)) + 2.0f);
				tr3->SetChild(r2);
				CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
				sep3->SetChild(tr3);

				m_fwfences->AddChild(sep3);
			}
			else
			{
				CSgPtr<CSgTranslate> tr4 = new CSgTranslate((2.0f * (l-30)) + 46.0f, 0.0f, 1.0f);
				tr4->SetChild(m_fence);
				CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
				sep4->SetChild(tr4);

				m_fwfences->AddChild(sep4);
			}
			CSgPtr<CSgMaterial> fenceMatYEL = new CSgMaterial(50.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f);
			fenceMatYEL->SetChild(m_fwfences);

			CSgPtr<CSgSeparator> sepFW = new CSgSeparator();
			sepFW->SetChild(fenceMatYEL);
			m_root->AddChild(sepFW);
		}
	}

	//Observation Tower Fences
	for(int i = 0; i<16;i++)
	{
		CSgPtr<CSgComposite> m_fence2 = new CSgComposite();
		m_fence2->AddChild(Fence());
		CSgPtr<CSgRotate> rot = new CSgRotate(90.,0., 1., 0.);
		rot->SetChild(m_fence2);
		
		if(i%2)
		{
			CSgPtr<CSgTranslate> trs3 = new CSgTranslate(74.5f, 0.f, 1.1f + i/2 *2.1f);
			CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
			trs3->SetChild(rot);
			sep3->SetChild(trs3);
			m_root->AddChild(sep3);
		}
		else
		{
			CSgPtr<CSgTranslate> trs4 = new CSgTranslate(95.425f, 0.f, 1.1f + i/2 *2.1f);
			CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
			trs4->SetChild(rot);
			sep4->SetChild(trs4);
			m_root->AddChild(sep4);
		}
	}
	for(int i = 0; i<20;i++)
	{
		CSgPtr<CSgComposite> m_fence2 = new CSgComposite();
		m_fence2->AddChild(Fence());
		
		if(i%2)
		{
			// Makes the hole for the entrance
			if( i == 9)
				continue;

			CSgPtr<CSgTranslate> trs3 = new CSgTranslate(2.5f + i/2 *2.1f+ 73, 0.f, 17.075);
			CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
			trs3->SetChild(m_fence2);
			sep3->SetChild(trs3);
			m_root->AddChild(sep3);
		}
		else
		{
			CSgPtr<CSgTranslate> trs3 = new CSgTranslate(2.5f + i/2 *2.1f+ 73, 0.f, 0.f);
			CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
			trs3->SetChild(m_fence2);
			sep3->SetChild(trs3);
			m_root->AddChild(sep3);
		}

	}
	CSgPtr<CSgComposite> m_fence2 = new CSgComposite();
	m_fence2->AddChild(Fence());
	CSgPtr<CSgTranslate> trs12 = new CSgTranslate(82.8f, 0.f, 18.f);
	CSgPtr<CSgRotate> rot12 = new CSgRotate(90, 0., 1., 0.);
	rot12->SetChild(m_fence2);
	trs12->SetChild(rot12);
	CSgPtr<CSgSeparator> sep12 = new CSgSeparator();
	sep12->SetChild(trs12);
	m_root->AddChild(sep12);

	CSgPtr<CSgComposite> m_fence3 = new CSgComposite();
	m_fence3->AddChild(Fence());
	CSgPtr<CSgTranslate> trs13 = new CSgTranslate(85.f, 0.f, 18.f);
	CSgPtr<CSgRotate> rot13 = new CSgRotate(90, 0., 1., 0.);
	rot13->SetChild(m_fence3);
	trs13->SetChild(rot13);
	CSgPtr<CSgSeparator> sep13 = new CSgSeparator();
	sep13->SetChild(trs13);
	m_root->AddChild(sep13);

	CSgPtr<CSgComposite> m_fence5 = new CSgComposite();
	m_fence5->AddChild(Fence());
	CSgPtr<CSgTranslate> trs14 = new CSgTranslate(82.8f, 0.f, 20.1f);
	CSgPtr<CSgRotate> rot14 = new CSgRotate(90, 0., 1., 0.);
	rot14->SetChild(m_fence5);
	trs14->SetChild(rot14);
	CSgPtr<CSgSeparator> sep14 = new CSgSeparator();
	sep14->SetChild(trs14);
	m_root->AddChild(sep14);

	CSgPtr<CSgComposite> m_fence6 = new CSgComposite();
	m_fence6->AddChild(Fence());
	CSgPtr<CSgTranslate> trs15 = new CSgTranslate(85.f, 0.f, 20.1f);
	CSgPtr<CSgRotate> rot15 = new CSgRotate(90, 0., 1., 0.);
	rot15->SetChild(m_fence6);
	trs15->SetChild(rot15);
	CSgPtr<CSgSeparator> sep15 = new CSgSeparator();
	sep15->SetChild(trs15);
	m_root->AddChild(sep15);
	// 
	//	END OBSERVATION TOWER FENCES
	//
}

CSgPtr<CSgComposite> CarnivalBuilder::Fence()
{
	CSgPtr<CSgComposite> m_fence = new CSgComposite();

	CSgPtr<CSgOctagonalCylinder> pole1 = new CSgOctagonalCylinder(1.25f,0.05f);
	CSgPtr<CSgTranslate> tr1 = new CSgTranslate(-1.0f,0.625f,0.0f);
	tr1->SetChild(pole1);
	CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
	sep1->SetChild(tr1);
	m_fence->AddChild(sep1);

	CSgPtr<CSgOctagonalCylinder> pole2 = new CSgOctagonalCylinder(1.25f,0.05f);
	CSgPtr<CSgTranslate> tr2 = new CSgTranslate(1.0f,0.625f,0.0f);
	tr2->SetChild(pole2);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	sep2->SetChild(tr2);
	m_fence->AddChild(sep2);

	CSgPtr<CSgOctagonalCylinder> pole3 = new CSgOctagonalCylinder(2.05f,0.05f);
	CSgPtr<CSgRotate> rot1 = new CSgRotate(90.0,0,0,1);
	rot1->SetChild(pole3);
	CSgPtr<CSgTranslate> tr3 = new CSgTranslate(0.0f,1.25f,0.0f);
	tr3->SetChild(rot1);
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	sep3->SetChild(tr3);
	m_fence->AddChild(sep3);

	CSgPtr<CSgOctagonalCylinder> pole4 = new CSgOctagonalCylinder(2.0f,0.05f);
	CSgPtr<CSgRotate> rot2 = new CSgRotate(90.0,0,0,1);
	rot2->SetChild(pole4);
	CSgPtr<CSgTranslate> tr4 = new CSgTranslate(0.0f,0.62f,0.0f);
	tr4->SetChild(rot2);
	CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
	sep4->SetChild(tr4);
	m_fence->AddChild(sep4);

	return m_fence;
}

void CarnivalBuilder::YoYo()
{
	CSgPtr<CSgTranslate> translate = new CSgTranslate( 30.f, 0.f,10.f );

	translate->SetChild( m_yoyof.Create());
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(translate);

	m_root->AddChild(sep);
}

void CarnivalBuilder::FerrisWheel()
{
	CSgPtr<CSgTranslate> translate = new CSgTranslate( 50.f, 0.f,10.f );

	translate->SetChild( m_fw.Create());
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(translate);

	m_root->AddChild(sep);
}

void CarnivalBuilder::ObservationTower()
{
	CSgPtr<CSgTranslate> translate = new CSgTranslate( 80.f, 1.f, 10.f );

	translate->SetChild(m_obs.Create());
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(translate);

	m_root->AddChild(sep);
}

void CarnivalBuilder::Gravitron(void)
{
	LoadTexture( "gravRim", "grav1.bmp");
	LoadTexture( "gravBot", "grav2.bmp");
	LoadTexture( "gravTop", "grav3.bmp");
	LoadTexture( "gravBase", "grav4.bmp");

	m_Gravitron.topTex = GetTexture("gravTop");
	m_Gravitron.botTex = GetTexture("gravBot");
	m_Gravitron.rimTex = GetTexture("gravRim");
	m_Gravitron.baseTex = GetTexture("gravBase");

	CSgPtr<CSgTranslate> translate = new CSgTranslate( 10.f, 0.f,10.f );
	CSgPtr<CSgSeparator> sep = new CSgSeparator();

	translate->SetChild( m_Gravitron.Create() );
	sep->SetChild( translate );
	m_root->AddChild(sep);
}

void CarnivalBuilder::Scrambler()
{
	//ScramblerFactory m_scrambled;

	
	CSgPtr<CSgTranslate> translate = new CSgTranslate( 40.f, 0.f,40.f );
	translate->SetChild( m_scrambler.Create());
	CSgPtr<CSgSeparator> seperator = new CSgSeparator();
	seperator->SetChild(translate);

	m_root->AddChild(seperator);
}

CSgPtr<CSgComposite> CarnivalBuilder::Sidewalk(void)
{
	CSgPtr<CSgComposite> sidewalk = new CSgComposite();
	double v[8][4] = {{0., 0., 0., 1.},{1.9, 0., 0., 1.}, {1.9, 0., 1.9, 1.},
						{0., 0., 1.9, 1.}, {0., 0.1, 0., 1.}, {1.9, 0.1, 0., 1.},
						{1.9, 0.1, 1.9, 1.}, {0., 0.1, 1.9, 1.}};
    double n[6][4] = {{0, 0, 1, 0}, {1, 0, 0, 0}, {0, 0, -1, 0}, 
						{-1, 0, 0, 0}, {0, 1, 0, 0}, {0, -1, 0, 0}};

	double t[4][2] = {{0, 0}, {0,1}, {1, 0}, {1,1}};

	CSgPtr<CSgPolygon> bottom = new CSgPolygon();
	bottom->AddNormal(CGrVector(n[5]));
	bottom->AddTexCoord(CGrVector(t[1]));
	bottom->AddVertex(CGrVector(v[0]));
	bottom->AddTexCoord(CGrVector(t[0]));
	bottom->AddVertex(CGrVector(v[1]));
	bottom->AddTexCoord(CGrVector(t[2]));
	bottom->AddVertex(CGrVector(v[2]));
	bottom->AddTexCoord(CGrVector(t[3]));
	bottom->AddVertex(CGrVector(v[3]));

	sidewalk->AddChild(bottom);

	CSgPtr<CSgPolygon> left = new CSgPolygon();
	left->AddNormal(CGrVector(n[3]));
	left->AddTexCoord(CGrVector(t[1]));
	left->AddVertex(CGrVector(v[4]));
	left->AddTexCoord(CGrVector(t[0]));
	left->AddVertex(CGrVector(v[0]));
	left->AddTexCoord(CGrVector(t[2]));
	left->AddVertex(CGrVector(v[3]));
	left->AddTexCoord(CGrVector(t[3]));
	left->AddVertex(CGrVector(v[7]));

	//tex1->SetChild(left);
	sidewalk->AddChild(left);

	CSgPtr<CSgPolygon> right = new CSgPolygon();

	right->AddNormal(CGrVector(n[1]));
	right->AddTexCoord(CGrVector(t[2]));
	right->AddVertex(CGrVector(v[1]));
	right->AddTexCoord(CGrVector(t[3]));
	right->AddVertex(CGrVector(v[5]));
	right->AddTexCoord(CGrVector(t[1]));
	right->AddVertex(CGrVector(v[6]));
	right->AddTexCoord(CGrVector(t[0]));
	right->AddVertex(CGrVector(v[2]));

	//tex2->SetChild(right);
	sidewalk->AddChild(right);

	CSgPtr<CSgPolygon> back = new CSgPolygon();

	back->AddNormal(CGrVector(n[2]));
	back->AddTexCoord(CGrVector(t[0]));
	back->AddVertex(CGrVector(v[0]));
	back->AddTexCoord(CGrVector(t[2]));
	back->AddVertex(CGrVector(v[4]));
	back->AddTexCoord(CGrVector(t[3]));
	back->AddVertex(CGrVector(v[5]));
	back->AddTexCoord(CGrVector(t[1]));
	back->AddVertex(CGrVector(v[1]));

	sidewalk->AddChild(back);

	CSgPtr<CSgPolygon> front = new CSgPolygon();

	front->AddNormal(CGrVector(n[0]));
	front->AddTexCoord(CGrVector(t[0]));
	front->AddVertex(CGrVector(v[3]));
	front->AddTexCoord(CGrVector(t[2]));
	front->AddVertex(CGrVector(v[2]));
	front->AddTexCoord(CGrVector(t[3]));
	front->AddVertex(CGrVector(v[6]));
	front->AddTexCoord(CGrVector(t[1]));
	front->AddVertex(CGrVector(v[7]));

	sidewalk->AddChild(front);

	CSgPtr<CSgPolygon> top = new CSgPolygon();

	top->AddNormal(CGrVector(n[4]));
	top->AddTexCoord(CGrVector(t[0]));
	top->AddVertex(CGrVector(v[5]));
	top->AddTexCoord(CGrVector(t[2]));
	top->AddVertex(CGrVector(v[4]));
	top->AddTexCoord(CGrVector(t[3]));
	top->AddVertex(CGrVector(v[7]));
	top->AddTexCoord(CGrVector(t[1]));
	top->AddVertex(CGrVector(v[6]));

	CSgPtr<CSgTexture> tex1 = new CSgTexture(m_sidewalk);
	tex1->SetChild(top);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	sep2->SetChild(tex1);
	sidewalk->AddChild(sep2);

	
	CSgPtr<CSgComposite> final = new CSgComposite();

	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(sidewalk);
	final->AddChild(sep);

	
	return final;
}

void CarnivalBuilder::Sidewalks(void)
{
	for(int i = 0; i < 52; i++)
	{
		CSgPtr<CSgComposite> m_sidewalks = new CSgComposite();
		m_sidewalks->AddChild(Sidewalk());
		CSgPtr<CSgTranslate> trs1 = new CSgTranslate(i*1.91f, 0.f, 22.f);
		CSgPtr<CSgSeparator> sep = new CSgSeparator();
		trs1->SetChild(m_sidewalks);
		sep->SetChild(trs1);
		m_root->AddChild(sep);
	}
	CSgPtr<CSgComposite> m_sidewalk4 = new CSgComposite();
	m_sidewalk4->AddChild(Sidewalk());
	CSgPtr<CSgTranslate> trs3 = new CSgTranslate(83.f, 0.f, 21.9f);
	CSgPtr<CSgRotate> rot1 = new CSgRotate(90, 0., 1., 0.);
	rot1->SetChild(m_sidewalk4);
	trs3->SetChild(rot1);
	CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
	sep1->SetChild(trs3);
	m_root->AddChild(sep1);

	CSgPtr<CSgComposite> m_sidewalks2 = new CSgComposite();
	m_sidewalks2->AddChild(Sidewalk());
	CSgPtr<CSgTranslate> trs5 = new CSgTranslate(83.f, 0.f, 19.99f);
	CSgPtr<CSgRotate> rot3 = new CSgRotate(90, 0., 1., 0.);
	rot3->SetChild(m_sidewalks2);
	trs5->SetChild(rot3);
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	sep3->SetChild(trs5);
	m_root->AddChild(sep3);

	CSgPtr<CSgComposite> m_sidewalks1 = new CSgComposite();
	m_sidewalks1->AddChild(Sidewalk());
	CSgPtr<CSgTranslate> trs4 = new CSgTranslate(83.f, 0.f, 18.08f);
	CSgPtr<CSgRotate> rot2 = new CSgRotate(90, 0., 1., 0.);
	rot2->SetChild(m_sidewalks1);
	trs4->SetChild(rot2);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	sep2->SetChild(trs4);
	m_root->AddChild(sep2);

	for(int j = 0; j< 3; j++)
	{
		CSgPtr<CSgComposite> m_sidewalks5 = new CSgComposite();
		m_sidewalks5->AddChild(Sidewalk());
		CSgPtr<CSgTranslate> trs5 = new CSgTranslate(30.f, 0.f, 21.9 - (j*1.91f));
		CSgPtr<CSgRotate> rot5 = new CSgRotate(90, 0., 1., 0.);
		rot5->SetChild(m_sidewalks1);
		trs5->SetChild(rot5);
		CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
		sep5->SetChild(trs5);
		m_root->AddChild(sep5);
	}
	for(int j = 0; j< 3; j++)
	{
		CSgPtr<CSgComposite> m_sidewalks6 = new CSgComposite();
		m_sidewalks6->AddChild(Sidewalk());
		CSgPtr<CSgTranslate> trs6 = new CSgTranslate(55.f, 0.f, 21.9 - (j*1.91f));
		CSgPtr<CSgRotate> rot6 = new CSgRotate(90, 0., 1., 0.);
		rot6->SetChild(m_sidewalks6);
		trs6->SetChild(rot6);
		CSgPtr<CSgSeparator> sep6 = new CSgSeparator();
		sep6->SetChild(trs6);
		m_root->AddChild(sep6);
	}
}